<template>
    <lay-config-provider :locale="local" :locales="locales">
      <!-- 表格 -->
      <lay-table
        id="id"
        :height="'100%'"
        :columns="columns"
        :data-source="dataSource"
        :default-toolbar="defaultToolbar"
      >
        <template v-slot:toolbar>
          <lay-button
            v-permission="PerKey.TaskTempalte_Index"
            size="sm"
            type="normal"
            @click="getTaskTemplateList"
            >{{ t("agvType.quiry") }}</lay-button
          >
          <lay-button
            v-permission="PerKey.TaskTempalte_Add"
            size="sm"
            type="primary"
            @click="addTaskTempalteList()"
            >{{ t("agvType.addition") }}</lay-button
          >
        </template>
  
        <template v-slot:birthday="{ data }"> {{ data.birthday }} </template>
        <template v-slot:code="{ data }"> {{ t("taskTempl.code") }} </template>
        <template v-slot:action="{ data }">
          {{ t("taskTempl.action") }}
        </template>
        <template v-slot:Operator="{ data }">
          {{ t("bindInform.Operator") }}
        </template>
  
        <template v-slot:operator="{ data }">
          <lay-button v-permission="PerKey.TaskTempalte_Eidt" size="xs" @click="edit(data)">
            {{ t("agvType.edit") }}
          </lay-button>
          <lay-button v-permission="PerKey.TaskTempalte_Delete" size="xs" type="danger" @click="delRobots(data.code)">
            {{ t("agvType.delete") }}
          </lay-button>
        </template>
        <template v-slot:subtask_type="{ data }">
          <lay-button size="xs" @click="ShowTasks(data)">
           {{t("taskTempl.action")}}
          </lay-button>
        </template>
      </lay-table>
      <template>
        <lay-page
          v-model="current5"
          v-model:limit="limit5"
          :pages="pages5"
          :total="total5"
          :show-count="true"
          :show-page="true"
          :show-limit="true"
          :show-refresh="true"
          :showSkip="true"
          @change="change5"
        ></lay-page>
      </template>
  
      <lay-layer class="layer" v-model="visible"  :shade="false" :area="['100%', '100%']" >
        <lay-button type="primary" class="closeGraphLayer" @click="closeGraph()">下一步</lay-button>
        <div class="box">
          <div id="sidebar">
            <div class="node-item" data-type="group">
              <span class="icon" style="color: green;">●</span> 群组节点
            </div>
            <div style="width:100%;height:30px;border-bottom:1px solid;margin:0 0 10px 0;">动作指令节点</div>
            <div class="node-item" data-type="No-action">
              <span class="icon" style="color: blue;">⚬</span> 无动作指令
            </div>
            <div class="node-item" data-type="forklift">
              <span class="icon" style="color: purple;">⚙</span> 叉车操作
            </div>
            <div class="node-item" data-type="jacking">
              <span class="icon" style="color: red;">■</span> 顶升
            </div>
            <div class="node-item" data-type="roller">
              <span class="icon" style="color: red;">■</span> 辊筒
            </div>
            <div class="node-item" data-type="Roboticarm">
              <span class="icon" style="color: red;">■</span> 机械臂
            </div>
            <div class="node-item" data-type="Manual">
              <span class="icon" style="color: red;">■</span> 人工
            </div>
          </div>
          <!-- 右侧画布 -->
          <div id="container">
            
          </div>
          <el-drawer  v-model="drawer2" :direction="direction">
            <template #header>
              <h4>{{t('taskTempl.属性面板')}}</h4>
            </template>
            <template #default>
              <el-form
                :label-position="labelPosition"
                label-width="auto"
                :model="formLabelAlign"
                style="max-width: 600px"
              >
                  <div v-show="taskTemplate.action_type==null">
                    <el-form-item :label="t('taskTempl.indexes')" :label-position="itemLabelPosition">
                      <el-input v-model="taskTemplate.index" />
                    </el-form-item>
                    <el-form-item :label="t('taskTempl.WhetherToIgnore')" :label-position="itemLabelPosition">
                      <lay-select placeholder="" v-model="taskTemplate.ignore">
                          <!-- <lay-select-option label="请选择"></lay-select-option> -->
                          <lay-select-option :value="true" :label="t('taskTempl.allow')"></lay-select-option>
                          <lay-select-option :value="false" :label="t('taskTempl.notAllow')"></lay-select-option>
                      </lay-select>
                    </el-form-item>
                    <el-form-item :label="t('taskTempl.WhetherToUseSecondaryPositioning')" :label-position="itemLabelPosition">
                      <lay-select placeholder="" v-model="taskTemplate.is_reposition">
                          <!-- <lay-select-option label="请选择"></lay-select-option> -->
                          <lay-select-option :value="true" :label="t('taskTempl.allow')"></lay-select-option>
                          <lay-select-option :value="false" :label="t('taskTempl.notAllow')"></lay-select-option>
                      </lay-select>
                    </el-form-item>
                    <el-form-item :label="t('taskTempl.TargetPointType')" :label-position="itemLabelPosition">
                      <lay-select placeholder="" v-model="taskTemplate.site_type">
                          <lay-select-option :value="1" :label="t('taskTempl.destination')"></lay-select-option>
                          <lay-select-option :value="2" :label="t('taskTempl.BeforeTheFinishLine')"></lay-select-option>
                          <lay-select-option :value="3" :label="t('taskTempl.PointOfRotation')"></lay-select-option>
                      </lay-select>
                    </el-form-item>
                    <el-form-item :label="t('taskTempl.taskType')" :label-position="itemLabelPosition">
                      <lay-select placeholder="" v-model="taskTemplate.subtask_type">
                          <lay-select-option :label="t('taskTempl.WalkingTasks')" :value="3"></lay-select-option>
                          <lay-select-option :label="t('taskTempl.PickupTask')" :value="4"></lay-select-option>
                          <lay-select-option :label="t('taskTempl.PlacementTask')" :value="5"></lay-select-option>
                          <lay-select-option :label="t('taskTempl.ChargingTask')" :value="6"></lay-select-option>
                          <lay-select-option :label="t('taskTempl.换电任务')" :value="7"></lay-select-option>
                          <lay-select-option :label="t('taskTempl.StandbyDuty')" :value="8"></lay-select-option>
                          <lay-select-option :label="t('taskTempl.detectionTask')" :value="9"></lay-select-option>
                          <lay-select-option :label="t('taskTempl.原地检测任务')" :value="10"></lay-select-option>
                      </lay-select>
                    </el-form-item>
                  </div>
                  <div v-show="taskTemplate.action_type==-1">
                    <el-form-item :label="t('taskTempl.ActionType')" :label-position="itemLabelPosition">
                      <lay-select placeholder="" v-model="taskTemplate.action_type">
                          <lay-select-option :label="t('taskTempl.NoActionCommand')" :value="-1"></lay-select-option>
                      </lay-select>
                    </el-form-item>
                    <el-form-item v-if="taskTemplate.action_type != 4" :label="t('taskTempl.DetectionType')" prop="detection_type">
                        <lay-select placeholder="" v-model="taskTemplate.detection_type">
                            <!-- <lay-select-option label=""></lay-select-option> -->
                            <lay-select-option :value="-1" :label="t('taskTempl.NoDetect')"></lay-select-option>
                            <lay-select-option :value="1" :label="t('taskTempl.EmptySupportDetection')"></lay-select-option>
                            <lay-select-option :value="2" :label="t('taskTempl.FullTrayDetection')"></lay-select-option>
                        </lay-select>
                    </el-form-item>
  
                  </div>
                  <div v-show="taskTemplate.action_type==1">
                    <el-form-item :label="t('taskTempl.ActionType')" :label-position="itemLabelPosition">
                      <lay-select placeholder="" v-model="taskTemplate.action_type">
                        <lay-select-option :value="1" :label="t('taskTempl.ForkliftOperation')"></lay-select-option>
                      </lay-select>
                    </el-form-item>
                    <el-form-item v-if="taskTemplate.action_type != 4" :label="t('taskTempl.DetectionType')" prop="detection_type">
                        <lay-select placeholder="" v-model="taskTemplate.detection_type">
                            <lay-select-option :value="-1" :label="t('taskTempl.NoDetect')"></lay-select-option>
                            <lay-select-option :value="1" :label="t('taskTempl.EmptySupportDetection')"></lay-select-option>
                            <lay-select-option :value="2" :label="t('taskTempl.FullTrayDetection')"></lay-select-option>
                        </lay-select>
                    </el-form-item>
                    <lay-form  :label-position="labelPosition3" >
                        <el-form-item  :label="t('taskTempl.angleOfPitch')" prop="pitch" >
                            <lay-select placeholder="" v-model="taskTemplate.fork['pitch']">
                                <lay-select-option :value="-1" :label="t('taskTempl.nonuse')"></lay-select-option>
                                <lay-select-option :value="1" :label="t('taskTempl.angleOfDepression')"></lay-select-option>
                                <lay-select-option :value="2" :label="t('taskTempl.ForkliftOperation')"></lay-select-option>
                            </lay-select>
                        </el-form-item>
                        <el-form-item :label="t('taskTempl.RollUp')" prop="roll" >
                            <lay-input type="number" :min=-1 v-model="taskTemplate.fork['roll']" placeholder="滚卷(X轴旋转)"></lay-input>
                        </el-form-item>
                        <el-form-item :label="t('taskTempl.FrontAndRearDirectionsX')" prop="x"  style="position: relative;"> 
                            <img style="position:absolute;top:10px;left:-120px;" src="../../../assets/icon/空心问号.png" alt="" :title="t('taskTempl.解释说明')">
                            <lay-input type="number" :min=-1 v-model="taskTemplate.fork['x']" placeholder=""></lay-input>
                        </el-form-item>
                        <el-form-item :label="t('taskTempl.FrontAndRearDirectionY')" prop="y"  style="position: relative;">
                            <img style="position:absolute;top:10px;left:-120px;" src="../../../assets/icon/空心问号.png" alt="" :title="t('taskTempl.解释说明')">
                            <lay-input type="number" :min=-1 v-model="taskTemplate.fork['y']" placeholder="前后方向(Y轴)"></lay-input>
                        </el-form-item>
                        <el-form-item :label="t('taskTempl.AngleZ')" prop="yaw" >
                            <lay-input type="number" :min=-1 v-model="taskTemplate.fork['yaw']" placeholder=""></lay-input>
                        </el-form-item>
                        <el-form-item :label="t('taskTempl.UpAndDownDirectionZ')" prop="z" >
                            <lay-select placeholder="" v-model="taskTemplate.fork['z']">
                                <lay-select-option :value="-1" :label="t('taskTempl.nonuse')"></lay-select-option>
                                <lay-select-option :value="1" :label="t('taskTempl.ShelfLayer')"></lay-select-option>
                                <lay-select-option :value="2" :label="t('taskTempl.UpliftedBed')"></lay-select-option>
                            </lay-select>
                        </el-form-item>
                    </lay-form>
  
                  </div>
                  <div v-show="taskTemplate.action_type==2">
                    <el-form-item :label="t('taskTempl.ActionType')" :label-position="itemLabelPosition">
                      <lay-select placeholder="" v-model="taskTemplate.action_type">
                        <lay-select-option :value="2" :label="t('taskTempl.jacking')"></lay-select-option>
                      </lay-select>
                    </el-form-item>
                    <el-form-item v-if="taskTemplate.action_type != 4" :label="t('taskTempl.DetectionType')" prop="detection_type">
                        <lay-select placeholder="" v-model="taskTemplate.detection_type">
                            <!-- <lay-select-option label=""></lay-select-option> -->
                            <lay-select-option :value="-1" :label="t('taskTempl.NoDetect')"></lay-select-option>
                            <lay-select-option :value="1" :label="t('taskTempl.EmptySupportDetection')"></lay-select-option>
                            <lay-select-option :value="2" :label="t('taskTempl.FullTrayDetection')"></lay-select-option>
                        </lay-select>
                    </el-form-item>
                    <el-form-item :label="t('taskTempl.rotationMode')" prop="mode" >
                      <lay-select placeholder="" v-model="taskTemplate.jack['mode']">
                          <lay-select-option :value="-1" :label="t('taskTempl.nonuse')"></lay-select-option>
                          <lay-select-option :value="0" :label="t('taskTempl.jacking')"></lay-select-option>
                          <lay-select-option :value="1" :label="t('taskTempl.pureRotation')"></lay-select-option>
                      </lay-select>
                    </el-form-item>
                    <el-form-item  :label="t('taskTempl.rotationAngle')" prop="rotate" >
                        <lay-input v-model="taskTemplate.jack['rotate']" placeholder=""></lay-input>
                    </el-form-item>
                    <el-form-item :label="t('taskTempl.jackingLevel')" prop="uplift" >
                        <lay-input v-model="taskTemplate.jack['uplift']"  placeholder=""></lay-input>
                    </el-form-item>
                  </div>
                  <div v-show="taskTemplate.action_type==3">
                    <el-form-item :label="t('taskTempl.ActionType')" :label-position="itemLabelPosition">
                      <lay-select placeholder="" v-model="taskTemplate.action_type">
                        <lay-select-option :value="3" :label="t('taskTempl.roller')"></lay-select-option>
                      </lay-select>
                    </el-form-item>
                    <el-form-item v-if="taskTemplate.action_type != 4" :label="t('taskTempl.DetectionType')" prop="detection_type">
                        <lay-select placeholder="" v-model="taskTemplate.detection_type">
                            <!-- <lay-select-option label=""></lay-select-option> -->
                            <lay-select-option :value="-1" :label="t('taskTempl.NoDetect')"></lay-select-option>
                            <lay-select-option :value="1" :label="t('taskTempl.EmptySupportDetection')"></lay-select-option>
                            <lay-select-option :value="2" :label="t('taskTempl.FullTrayDetection')"></lay-select-option>
                        </lay-select>
                    </el-form-item>
                    <div >
                      <lay-button @click="addActionFormRoller(index)" class="tool-button-icon-addForm" style="background: url(/icon/addForm.png) center no-repeat;border: none;float:right;"></lay-button>
                     
                    </div>
                    <div v-for="itemRoller,index in taskTemplate.roller">
                      <div style="display:flex;">
                        <lay-button @click="delActionFormRoller(index)" class="tool-button-icon-delForm" style="background: url(/icon/delForm.png) center no-repeat;border: none;float: right;"></lay-button>
                      </div>
                        <el-form-item  :label="t('taskTempl.RollerInstructions')" prop="roller " label-width="188">
                          <lay-select placeholder="" v-model="itemRoller['mode']">
                                <!-- <lay-select-option label="请选择"></lay-select-option> -->
                                <lay-select-option :value="-1" :label="t('taskTempl.nonuse')"></lay-select-option>
                                <lay-select-option :value="1" :label="t('taskTempl.FrontEndFeeding')"></lay-select-option>
                                <lay-select-option :value="2" :label="t('taskTempl.FrontEndRelease')"></lay-select-option>
                                <lay-select-option :value="3" :label="t('taskTempl.FeedFromTheBackEnd')"></lay-select-option>
                                <lay-select-option :value="4"  :label="t('taskTempl.BackEndDelivery')"></lay-select-option>
                            </lay-select>
                        </el-form-item>
                        <el-form-item :label="t('taskTempl.lary')" prop="floor" label-width="188">
                                <lay-input type="number" :min="0" v-model="itemRoller['floor']" placeholder=""></lay-input>
                        </el-form-item>
                    </div>
                  </div>
                  <div v-show="taskTemplate.action_type==4">
                    <el-form-item :label="t('taskTempl.ActionType')" :label-position="itemLabelPosition">
                      <lay-select placeholder="" v-model="taskTemplate.action_type">
                        <lay-select-option :value="4" :label="t('taskTempl.Labour')"></lay-select-option>
                      </lay-select>
                    </el-form-item>
                    <el-form-item v-if="taskTemplate.action_type != 4" :label="t('taskTempl.DetectionType')" prop="detection_type">
                        <lay-select placeholder="" v-model="taskTemplate.detection_type">
                            <!-- <lay-select-option label=""></lay-select-option> -->
                            <lay-select-option :value="-1" :label="t('taskTempl.NoDetect')"></lay-select-option>
                            <lay-select-option :value="1" :label="t('taskTempl.EmptySupportDetection')"></lay-select-option>
                            <lay-select-option :value="2" :label="t('taskTempl.FullTrayDetection')"></lay-select-option>
                        </lay-select>
                    </el-form-item>
                    <el-form-item v-if="taskTemplate.action_type == 4" :label="t('taskTempl.manualCommand')" prop="manual_work">
                          <lay-input  v-model="taskTemplate.manual['audio_code']" placeholder=""></lay-input>
                      </el-form-item>
                  </div>
                  <div v-show="taskTemplate.action_type==5">
                    <el-form-item :label="t('taskTempl.ActionType')" :label-position="itemLabelPosition">
                      <lay-select placeholder="" v-model="taskTemplate.action_type">
                        <lay-select-option :value="5" :label="t('taskTempl.robotArm')"></lay-select-option>
                      </lay-select>
                    </el-form-item>
                    <el-form-item v-if="taskTemplate.action_type != 4" :label="t('taskTempl.DetectionType')" prop="detection_type">
                        <lay-select placeholder="" v-model="taskTemplate.detection_type">
                            <lay-select-option :value="-1" :label="t('taskTempl.NoDetect')"></lay-select-option>
                            <lay-select-option :value="1" :label="t('taskTempl.EmptySupportDetection')"></lay-select-option>
                            <lay-select-option :value="2" :label="t('taskTempl.FullTrayDetection')"></lay-select-option>
                        </lay-select>
                    </el-form-item>
                    <lay-form  :label-position="labelPosition3" style="padding: 20px;">
                        <lay-button @click="addArmActions">增加机械臂配置</lay-button>
                        <div v-for="it,index in taskTemplate.arm_action" style="border:1px solid #ccc;margin-top:10px;padding:20px;">
                            <div style="display: flex;justify-content: flex-end;margin-bottom:5px; ">
                              <lay-button @click="delActionFormArm(index)" class="tool-button-icon-delForm" style="background: url(/icon/delForm.png) center no-repeat;border: none;"></lay-button>
                            </div>
                            <el-form-item :label="t('taskTempl.程序编号')" prop="" >
                                <lay-input type="number" :min=0 v-model="it.program_code" placeholder=""></lay-input>
                            </el-form-item>
                            <el-form-item :label="t('taskTempl.程序名称')" prop="" >
                                <lay-input   v-model="it.program_name" placeholder=""></lay-input>
                            </el-form-item>
                            <el-form-item :label="t('taskTempl.机械臂名称')" prop="robot_name" >
                                <lay-input  v-model="it.robot_name" placeholder=""></lay-input>
                            </el-form-item>
                            <el-form-item :label="t('taskTempl.动作指令编号')" prop="" >
                                <lay-input type="number" :min=0 v-model="it.arm_action_code" placeholder=""></lay-input>
                            </el-form-item>
                            <el-form-item :label="t('taskTempl.设备指令编号')" prop="" >
                                <lay-input type="number" :min=0 v-model="it.dev_action_code" placeholder=""></lay-input>
                            </el-form-item>
                            <el-form-item :label="t('taskTempl.机械臂坐标索引')" prop="" >
                                <lay-input type="number" :min=0 v-model="it.car_points" placeholder=""></lay-input>
                            </el-form-item>
                            <el-form-item :label="t('taskTempl.点位机械臂坐标索引')" prop="" >
                                <lay-input type="number" :min=0 v-model="it.stock_points" placeholder=""></lay-input>
                            </el-form-item>
                        </div>
                    </lay-form>
                  </div>
              </el-form>
            </template>
          </el-drawer>
       </div>
      </lay-layer>
      <el-dialog v-model="dialogFormCode" title="请填写模板编号" width="500">
        <el-form :model=" taskModel">
          <el-form-item label="模板编号" :label-width="formLabelWidth">
            <el-input v-model=" taskModel.code"  />
          </el-form-item>
        </el-form>
        <template #footer>
          <div class="dialog-footer">
            <el-button @click="dialogFormCancel">取消</el-button>
            <el-button type="primary" @click="dialogFormVisible">
              确定
            </el-button>
          </div>
        </template>
      </el-dialog>
    </lay-config-provider>
  </template>
  <script setup>
  import NoAction from "../../../assets/tasktemplate/NoAction.png";
  import { ref, onMounted, watchEffect,computed, nextTick } from "vue";
  import zn from "@/local/zh_CN";
  import en from "@/local/en_US";
  import { useI18n } from "@layui/layui-vue";
  import {
    get_task_template_list,
    add_task_template,
    edit_task_template,
    del_task_template,
  } from "../../../api/module/setup/task_template";
  import { PerKey } from "../../../library/permissionConst"
  import { useAgvRobotsStore } from "../../../store/setup/agv_type";
  import { Graph, Shape,Addon, Node, Cell } from "@antv/x6";
  // form表单label位置
  const labelPosition = ref('left')
  const itemLabelPosition = ref('')
  /**属性面板 */
  const drawer2= ref(false);
  const direction = ref("rtl");
  /**中英文转换所需 */
  const store = useAgvRobotsStore();
  const { t } = useI18n();
  const labelPosition3 = ref("left");
  const locales = [
    { name: "zh_CN", locale: zn, merge: true },
    { name: "en_US", locale: en, merge: true },
  ];
  
  const local = ref(store.$state.local);
  watchEffect(() => {
    local.value = store.$state.local;
  });
  /**数据源 */
  const dataSource = ref()
  /**初始化 */
  onMounted(() => {
    getTaskTemplateList();
  });
  /**获取任务模板数据 */
  const getTaskTemplateList = () => {
    get_task_template_list().then((res) => {
      if (res.code == 0) {
        layer.notifiy({
          title: "Success",
          content: "",
          icon: 1,
          time: 2000,
        });
      } else {
        var contentEn = RmsErrorEnum(res.code);
        layer.notifiy({
          title: "Error",
          content: local.value == "en_US" ? contentEn : res.message,
          icon: 2,
        });
      }
      dataSource.value = res.data;
    });
  };
  /**弹窗控制 */
  const visible = ref(false);
  
  /**添加事件 */
  const addTaskTempalteList =() =>{
    visible.value = true;
    buildGraph();
    nextTick(()=>{
      dnd  = new Addon.Dnd({
        target: graph, // 目标画布
        scaled: false, // 不缩放
        animation: true, // 平滑动画
      });
      LoadGraphEvent();
    })
  };
  /**取消 */
  const dialogFormCancel = () =>{
    dialogFormCode.value = false;
    taskModel.value.code ="";
    taskModel.value.subtask_templates=[];
    taskTemplate.value = null
  }
  const fieldTypeMap = {
    actions: [
      {
        action_type: "number",
        arm_action: [
          {
            arm_action_code: "number",
            car_points: "number",
            dev_action_code: "number",
            program_code: "number",
            program_name: "string",
            relation: {
              point: { x: "number", y: "number" },
              source_port: "string",
              target_id: "number",
              target_port: "string"
            },
            robot_name: "string",
            stock_points: "number"
          }
        ],
        detection_type: "number",
        fork: {
          pitch: "number",
          relation: {
            point: { x: "number", y: "number" },
            source_port: "string",
            target_id: "number",
            target_port: "string"
          },
          roll: "number",
          x: "number",
          y: "number",
          yaw: "number",
          z: "number"
        },
        jack: {
          mode: "number",
          relation: {
            point: { x: "number", y: "number" },
            source_port: "string",
            target_id: "number",
            target_port: "string"
          },
          rotate: "number",
          uplift: "number"
        },
        manual: {
          relation: {
            point: { x: "number", y: "number" },
            source_port: "string",
            target_id: "number",
            target_port: "string"
          },
          voice_index: "number"
        },
        manual_work: "boolean",
        roller: [
          {
            floor: "number",
            mode: "number",
            relation: {
              point: { x: "number", y: "number" },
              source_port: "string",
              target_id: "number",
              target_port: "string"
            }
          }
        ]
      }
    ],
    ignore: "boolean",
    index: "number",
    is_reposition: "boolean",
    relation: {
      point: { x: "number", y: "number" },
      source_port: "string",
      target_id: "number",
      target_port: "string"
    },
    site_type: "number",
    subtask_type: "number"
  };
  /**确认 */
  const dialogFormVisible = () =>{
   taskModel.value.subtask_templates.forEach((subItem)=>{
    subItem.index = Number(subItem.index)
     subItem.actions.forEach((actionItem)=>{
         console.log(actionItem,"actionItem");
  
          if(actionItem.action_type==5){
            actionItem.arm_action.forEach((armItem)=>{
                  armItem.arm_action_code = Number(armItem.arm_action_code);
                  armItem.car_points = Number(armItem.car_points);
                  armItem.dev_action_code = Number(armItem.dev_action_code);
                  armItem.program_code = Number(armItem.program_code);
                  armItem.stock_points = Number(armItem.stock_points);
              });
          }
          if(actionItem.action_type == 1){
            actionItem.fork.pitch = Number(actionItem.fork.pitch);
            actionItem.fork.roll = Number(actionItem.fork.roll);
            actionItem.fork.x = Number(actionItem.fork.x);
            actionItem.fork.y = Number(actionItem.fork.y);
            actionItem.fork.yaw = Number(actionItem.fork.yaw);
            actionItem.fork.z = Number(actionItem.fork.z);
          }
          if(actionItem.action_type == 2){
            actionItem.jack.mode = Number(actionItem.jack.mode);
            actionItem.jack.rotate = Number(actionItem.jack.rotate);
            actionItem.jack.uplift = Number(actionItem.jack.uplift);
          }
          if(actionItem.action_type == 4){
            actionItem.manual.voice_index = Number(actionItem.manual.voice_index);
          }
          if(actionItem.action_type == 3){
            actionItem.roller.forEach((rollerItem)=>{
              rollerItem.mode = Number(rollerItem.mode);
              rollerItem.floor = Number(rollerItem.floor);
            })
          }
         
     })
   })
    console.log(taskModel.value,"taskModel.value我哦");
    add_task_template(taskModel.value).then((res)=>{
      if (res.code == 0) {
          layer.notifiy({
              title: "Success",
              content: "" ,
              icon: 1
          });
  
      } else {
          var contentEn =  RmsErrorEnum(res.code);
          layer.notifiy({
              title: "Error",
              content: local.value=="en_US"? contentEn: res.message,
              icon: 2
          })
      }
    })
  };
  
  
  /**画布参数值 */
  const taskTemplate=ref();
  /**画布 */
  let graph;
  /**画布左侧*/
  let stencil;
  let dnd;
  /**创建画布 */
  const buildGraph =()=>{
    nextTick(()=>{
       graph = new Graph({
        container: document.getElementById("container"),
        selecting: {
          enabled: true,
        },
        embedding: {
          enabled: true,
        },
        allowMultiEdges: true, // 允许多条边
        connecting: {
          snap: true,                 // 启用吸附
          allowBlank: false,          // 不允许连接到空白
          allowLoop: false,           // 不允许自环
          allowNode: true,           // 不允许连接到节点主体
          highlight: true,            // 高亮目标节点
        },
        interacting: {
          edgeMovable: true,          // 允许拖动边
        },
        keyboard: {
          enabled: true,
          global: true,
        },
        history: true,
        height: 900,
        background: {
          color: "#fefefe",          // 背景颜色
        },
        mousewheel: {
          enabled: true,
          modifiers: ["ctrl", "meta"],
        },
        grid: {
          size: 15,                  // 网格大小
          visible: true,
          type: "dot",
        },
        panning: {
          enabled: true,
        },
        
      });
      
    })
  }
  /**添加辊筒 */
  const addActionFormRoller =()=>{
    taskTemplate.value.roller.push({floor:0,mode:0});
  }
  /**删除辊筒配置 */
  const delActionFormRoller =(index)=>{
    taskTemplate.value.roller.splice(index,1)
  }
  /**添加机械臂配置 */
  const addArmActions = () =>{
    taskTemplate.value.arm_action.push({
      arm_action_code:0,
      car_points:0,
      dev_action_code:0,
      program_code:0,
      program_name:"",
      robot_name:"",
      stock_points:0
    });
  }
  /**删除机械臂配置 */
  const delActionFormArm = (index) =>{
     taskTemplate.value.arm_action.splice(index,1);
  }
  const taskModel=ref({
    code: "",
    subtask_templates: []
  })
  /**关闭保存画布数据 */
  const closeGraph = () => {
   
    const jsonData = graph.toJSON();
    console.log(jsonData, "jsonData--()--");
  
    // 找到所有 parentCell
    const parentCells = jsonData.cells.filter(cell => cell.shape === "rect" && cell.children);
    console.log(parentCells, "parentCells");
  
    // 遍历每个 parentCell
    parentCells.forEach(parentCell => {
      // 添加 parentCell 的数据到主模型
      taskModel.value.subtask_templates.push(parentCell.data);
  
      // 获取该 parentCell 的子节点
      const nodes = jsonData.cells.filter(cell => cell.shape === "rect" && cell.parent === parentCell.id);
      console.log(nodes, `nodes for parentCell ${parentCell.id}`);
  
      // 存储当前 parentCell 的节点顺序
      let orderedNodes =[];
      let currentNode = null;
  
      if (nodes.length <= 1) {
        // 如果只有一个节点，直接加入 orderedNodes
        if (nodes[0]) orderedNodes.push(nodes[0].data);
      } else {
        // 找到没有 target_id 的起始节点
        currentNode = nodes.find(node => !node.data.relation?.target_id);
        if (!currentNode) {
          console.log(`未找到没有 target_id 的节点 for parentCell ${parentCell.id}`);
          return;
        }
        // 按照 target_id 的顺序递归追踪节点
        while (nodes.length) {
          orderedNodes.unshift(currentNode.data); // 将当前节点的 data 添加到顺序数组
          const nextNode = nodes.find(node => node.data.relation?.target_id === currentNode.data.id); // 找到 target_id 指向的下一个节点
          if (!nextNode) break;
          currentNode = nextNode; // 移动到下一个节点
        }
      }
  
      console.log(orderedNodes, `orderedNodes for parentCell ${parentCell.id}`);
      // 将排序好的节点数据加入主模型
      // taskModel.value.subtask_templates[taskModel.value.subtask_templates.length - 1].actions.push(orderedNodes);
      Object.values(orderedNodes).forEach(node => {
        taskModel.value.subtask_templates[taskModel.value.subtask_templates.length - 1].actions.push(node);
      });
    });
    visible.value = false;
    // 设置对话框显示状态
    dialogFormCode.value = true;
    graph.dispose(); 
    console.log(taskModel.value, "taskModel.value哈哈哈");
  };
  
  // const closeGraph = () => {
  //   dialogFormCode.value = true;
  //   const jsonData = graph.toJSON();
  //   console.log(jsonData,"jsonData--()--");
  
  //   const parentCell = jsonData.cells.filter(cell=>cell.shape === "rect" && cell.children);
  //   console.log(parentCell,"parentCell");
  //   taskModel.value.subtask_templates.push(parentCell[0].data)
  //   // 获取所有 rect 类型的节点
  //   const nodes = jsonData.cells.filter(cell =>cell.shape === "rect" && cell.parent === parentCell[0].id);
  //   console.log(nodes,"nodes---");
  //   // 存储最终节点顺序的数组
  //   let orderedNodes = [];
  //   let currentNode =null;
  //   if(nodes.length<=1){
  //     orderedNodes.push(nodes[0].data)
  //   }else{
  //     currentNode = nodes.find(node => {
  //       return !node.data.relation.target_id; // 添加 return 明确返回布尔值
  //     }); // 找到没有 target_id 的节点，作为起点
  //     // 如果没有找到这种节点，说明数据不符合预期
  //     if (!currentNode) {
  //       console.log("未找到没有 target_id 的节点");
  //       return;
  //     }
  //     // 递归追踪节点的顺序
  //     while (nodes.length) {
  //       orderedNodes.unshift(currentNode.data);  // 将当前节点的 data 添加到顺序数组
  //       const nextNode = nodes.find(node => node.data.relation.target_id == currentNode.data.id);  // 找到 target_id 指向的下一个节点
  //       if(!nextNode) break;
  //       currentNode = nextNode;  // 移动到下一个节点
  //     }
  //   }
  //   console.log(orderedNodes,'orderedNodes');
  //   taskModel.value.subtask_templates[0].actions.push(orderedNodes);
  //   // visible.value = false;
  //   dialogFormCode.value = true;
  //   console.log(taskModel.value,"taskModel.value哈哈哈");
  // };
  
  
  /** 任务模板编号弹窗变量*/
  const dialogFormCode = ref(false);
  
  /**是否按下Ctrl脱离群组节点 */
  let ctrlPressed = false
  /**距离群组范围 */
  const embedPadding = 20
  /**选中节点的样式 */
  /**点击选中边或节点后添加样式 */
  let selectedElement = null;
  // 选中节点或边
  const selectElement = (element) => {
    // 清除之前的选中效果
    if (selectedElement) {
      if (selectedElement.isNode()) {
        // 恢复节点的默认边框颜色
        // selectedElement.attr('body/stroke', '#000000'); // 恢复为默认颜色（黑色）
        // selectedElement.attr('body/strokeWidth', 1);    // 恢复默认边框宽度
        selectedElement.removeTools();
      } else if (selectedElement.isEdge()) {
        // 恢复边的默认颜色
        selectedElement.attr('line/stroke', '#000000'); // 恢复为默认颜色（黑色）
        selectedElement.attr('line/strokeWidth', 1);   // 恢复默认宽度
      }
    }
  
    // 更新当前选中元素
    selectedElement = element;
  
    if (element.isNode()) {
      // 给节点添加选中效果
      element.addTools([{
              name: 'boundary',
              args: {
                attrs: {
                  fill: '#16B8AA',
                  stroke: '#2F80EB',
                  strokeWidth: 1,
                  fillOpacity: 0.1
                }
              }
            },
            ])
    } else if (element.isEdge()) {
      // 给边添加选中效果
      element.attr('line/stroke', 'blue'); // 改变边的颜色
      element.attr('line/strokeWidth', 3); // 加粗边
    }
  };
  /**节点id */
  const nodeNumber = ref(1);
  /**画布事件加载 */
  const LoadGraphEvent =()=>{
    graph.on('node:mouseup', ({ node ,x,y,}) => {
      console.log(node.data,x,y,"节点抬起");
         node.setData({
          ...node.data,
          relation:{
            point:{
              x:x,
              y:y
            }
          }
         });
    });
    graph.on('node:mousewheel', ({ node ,x,y,}) => {
      console.log(node.data,x,y,"节点抬起");
      node.setData({
          ...node.data,
          relation:{
            point:{
              x:x,
              y:y
            }
          }
         });
    });
    graph.on('node:dblclick',({cell})=>{
        drawer2.value = true;
        taskTemplate.value = cell.getData();
        console.log(taskTemplate.value.action_type,"数据（）-（）") ;
    })
    graph.on('blank:click', () => {
          if (selectedElement) {
              if (selectedElement.isNode()) {
                // 恢复节点的默认样式
                selectedElement.removeTools();
              } else if (selectedElement.isEdge()) {
                // 恢复边的默认样式
                selectedElement.attr('line/stroke', '#000000'); // 恢复为默认颜色
                selectedElement.attr('line/strokeWidth', 1);    // 恢复默认宽度
              }
              selectedElement = null; // 清空选中状态
            }
    });
    graph.on('node:click', ({ node }) => {
        selectElement(node); // 选中节点
    });
    graph.on('node:embedding', ({ e }) => {
      ctrlPressed = e.metaKey || e.ctrlKey
    })
    graph.on('node:embedded', () => {
      ctrlPressed = false
    })
    graph.on('node:change:size', ({ node, options }) => {
      if (options.skipParentHandler) {
        return
      }
  
      const children = node.getChildren()
      if (children && children.length) {
        node.prop('originSize', node.getSize())
      }
    });
    graph.on('node:change:position', ({ node, options }) => {
        if (options.skipParentHandler || ctrlPressed) {
          return
        }
  
        const children = node.getChildren()
        if (children && children.length) {
          node.prop('originPosition', node.getPosition())
        }
  
        const parent = node.getParent()
        if (parent && parent.isNode()) {
          let originSize = parent.prop('originSize')
          if (originSize == null) {
            originSize = parent.getSize()
            parent.prop('originSize', originSize)
          }
  
          let originPosition = parent.prop('originPosition')
          if (originPosition == null) {
            originPosition = parent.getPosition()
            parent.prop('originPosition', originPosition)
          }
  
          let x = originPosition.x
          let y = originPosition.y
          let cornerX = originPosition.x + originSize.width
          let cornerY = originPosition.y + originSize.height
          let hasChange = false
  
          const children = parent.getChildren()
          if (children) {
            children.forEach((child) => {
              const bbox = child.getBBox().inflate(embedPadding)
              const corner = bbox.getCorner()
  
              if (bbox.x < x) {
                x = bbox.x
                hasChange = true
              }
  
              if (bbox.y < y) {
                y = bbox.y
                hasChange = true
              }
  
              if (corner.x > cornerX) {
                cornerX = corner.x
                hasChange = true
              }
  
              if (corner.y > cornerY) {
                cornerY = corner.y
                hasChange = true
              }
            })
          }
  
          if (hasChange) {
            parent.prop(
              {
                position: { x, y },
                size: { width: cornerX - x, height: cornerY - y },
              },
              { skipParentHandler: true },
            )
          }
        }
      });
    graph.on("cell:dblclick", ({ cell }) => {
          console.log( cell.getData(),"cell---()");
    })
    // 监听鼠标移入和移出事件，显示/隐藏连接桩
    graph.on('node:mouseenter', ({ node }) => {
        node.getPorts().forEach(port => {
          node.portProp(port.id, 'attrs/circle/opacity', 1); // 显示连接桩
        });
       
      });
    graph.on('node:mouseleave', ({ node }) => {
        node.getPorts().forEach(port => {
          node.portProp(port.id, 'attrs/circle/opacity', 0); // 隐藏连接桩
        });
      });
    // 监听边正在连接时显示目标节点的连接桩
    graph.on('edge:connecting', ({ currentTarget }) => {
        const targetNode = currentTarget.getTargetCell();
        if (targetNode) {
          targetNode.getPorts().forEach(port => {
            targetNode.portProp(port.id, 'attrs/circle/opacity', 1); // 显示
          });
        }
    });
    graph.on('edge:connected', ({ edge,node }) => {
        graph.getNodes().forEach(node => {
          node.getPorts().forEach(port => {
            node.portProp(port.id, 'attrs/circle/opacity', 0); // 恢复隐藏
          });
        });
         // 获取源节点和目标节点
        const sourceNode = edge.getSourceNode();  // 获取源节点
        const targetNode = edge.getTargetNode();  // 获取目标节点
        const sourcePort = edge.getSource().port; // 获取源端口
        const targetPort = edge.getTarget().port; // 获取目标端口
        const sourceNodes = edge.getSourceNode()?.store.data.data.id;
        const targetNodes = edge.getTargetNode()?.store.data.data.id;
        sourceNode.setData({
          ...sourceNode.store.data.data, 
          relation:{
            target_id:targetNodes,
            source_port:sourcePort,
            target_port:targetPort,
          }
         
        });
    });
    //删除节点
    graph.bindKey("delete", () => {
      const cells =  graph.getSelectedCells();
      const jsonData = graph.toJSON();
      jsonData.cells.forEach((i)=>{
        switch (i.shape) {
          case "rect":
            if (i.data.target_id === cells[0].store.data.data.id) {
              const node = graph.getCell(i.id);  // 根据 ID 获取图形节点
              if (node) {
                node.setData({
                  ...node.store.data.data,  
                  target_id: "" 
                });
              }
            }
            break;
        }
      });
      if (cells.length) {
          graph.removeCells(cells);
      }
    });
    // 添加拖拽事件
    document.querySelectorAll('.node-item').forEach((item) => {
      item.addEventListener('mousedown', (e) => {
        const type = item.dataset.type;
        // 公共连接桩配置
        const portConfig = {
          groups: {
            top: {
              position: 'top',
              attrs: {
                circle: {
                  r: 4,
                  magnet: true,
                  stroke: '#000',
                  fill: '#fff',
                },
              },
            },
            bottom: {
              position: 'bottom',
              attrs: {
                circle: {
                  r: 4,
                  magnet: true,
                  stroke: '#000',
                  fill: '#fff',
                },
              },
            },
          },
          items: [
            { id: 'in', group: 'top' },  // 定义输入端口
            { id: 'out', group: 'bottom' },  // 定义输出端口
          ],
        };
        // 定义节点样式和配置
        let nodeConfig = {
          width: 100,
          height: 40,
          attrs: {
            body: {
              fill: '#ffffff',
              stroke: '#000000',
              rx: 6,
              ry: 6,
            },
            label: {
              text: '',
              fill: '#333333',
              fontSize: 12,
            },
          },
          ports: portConfig, // 添加连接桩配置
          data: {
           
          },
        };
        // 针对不同类型的节点
        if (type === 'group') {
          nodeConfig = {
            shape: 'rect',
            width: 300,
            height: 200,
            zIndex: -1,
            attrs: {
              body: {
                stroke: '#ffa940',
                strokeDasharray: '10,5',
                fill: '#fffbe6',
              },
              label: {
                text: '群组节点',
                fill: '#d48806',
                fontSize: 14,
                fontWeight: 'bold',
              },
            },
            ports: portConfig, // 群组节点也添加连接桩
            data: {
                index:"",
                is_reposition:"",
                site_type:"",
                subtask_type:"",
                actions:[],
                relation:{
                  point:{x:"",y:""},
                  source_port:"",
                  target_id:0,
                  target_port:""
                }
            },
          };
        } else if (type === 'No-action') {
          nodeConfig.attrs.label.text = '无动作指令';
          nodeConfig.attrs.body.stroke = '#28a745';
          nodeConfig.data = { action_type:-1,detection_type:"", };
        } else if (type === 'forklift') {
          nodeConfig.attrs.label.text = '叉车操作';
          nodeConfig.attrs.body.stroke = '#007bff';
          nodeConfig.data = { action_type:1,detection_type:"", fork:{pitch:"",roll:"",x:"",y:"",yaw:"",z:"" } };
        } else if (type === 'jacking') {
          nodeConfig.attrs.label.text = '顶升';
          nodeConfig.attrs.body.stroke = '#6f42c1';
          nodeConfig.data = { action_type:2,detection_type:"",jack: {mode:"",rotate:"",uplift:""} };
        } else if (type === 'roller') {
          nodeConfig.attrs.label.text = '辊筒';
          nodeConfig.attrs.body.stroke = '#dc3545';
          nodeConfig.data = { action_type:3,detection_type:"", roller: [{floor:"",mode:""}]};
        }else if (type === 'Roboticarm') {
          nodeConfig.attrs.label.text = '机械臂';
          nodeConfig.attrs.body.stroke = '#dc3545';
          nodeConfig.data = { action_type:5,detection_type:"", arm_action:[{arm_action_code:"",car_points:"",dev_action_code:"",program_code:"",program_name:"",robot_name:"",stock_points:""}]};
        }
        else if (type === 'Manual') {
          nodeConfig.attrs.label.text = '人工';
          nodeConfig.attrs.body.stroke = '#dc3545';
          nodeConfig.data = { action_type:4,detection_type:"", manual: {audio_code: 0}};
        }
        nodeConfig.data.id = nodeNumber.value++;
  
        
        // 创建节点
        const node = graph.createNode(nodeConfig);
        
        console.log(node,"???");
        // 开始拖拽
        dnd.start(node, e);
      });
    });
  }
  const columns = [
    {
      title: computed(() => t("taskTempl.code")),
      width: "100px",
      sort: true,
      fixed: "left",
      align: "center",
      titleSlot: "code",
      key: "code",
    },
    {
      title: computed(() => t("taskTempl.action")),
      width: "150px",
      sort: true,
      align: "center",
      // titleSlot: "detection_type",
      // customSlot: "subtask_type",
      titleSlot: "action",
      key: "action",
      // key: "detection_type",
      // 货物检测类型指令（不启用、空托检测、满托检测）,
    },
    {
      title: computed(() => t("agvType.operation")),
      width: "220px",
      align: "center",
      fixed: "right",
      titleSlot: "Operator",
      customSlot: "operator",
    },
  ];
  </script>
  <style scoped>
  
  /* 左侧侧边栏样式 */
  #sidebar {
    width: 200px;
    background-color: #f8f8f8;
    padding: 10px;
    box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
  }
  
  .node-item {
    display: flex;
    align-items: center;
    padding: 10px;
    margin-bottom: 10px;
    background: #fff;
    border: 1px solid #e0e0e0;
    border-radius: 8px;
    cursor: grab;
    font-size: 14px;
  }
  
  .node-item:hover {
    background-color: #f0f7ff;
  }
  
  .icon {
    margin-right: 8px;
    font-size: 16px;
  }
  
  /* 右侧画布 */
  #container {
    flex: 1;
    background-color: #fff;
  }
  
  /* 给 lay-layer 弹窗设置一个 flex 布局容器 */
  .box {
    display: flex;
    flex-direction: row; /* 水平布局 */
    width: 98vw;
    height: 94vh;
    box-sizing: border-box;
    overflow: hidden;
    margin: 0;
  }
  
  /* 左侧侧边栏样式 */
  .dnd-container {
    min-width: 280px; /* 固定宽度 */
    height: 100%;
    /* height: 100vh; */
    overflow-y: auto; /* 滚动条以防内容溢出 */
    background-color: #f0f0f0; /* 侧边栏背景色 */
    padding: 10px;
    box-sizing: border-box; /* 确保 padding 不会增加元素的总宽度 */
    border-right: 1px solid #f4bd26; /* 分隔线 */
  }
  
  /* 右侧画布样式 */
  .graph-container {
    flex-grow: 1; /* 占据剩余的宽度 */
    height: 100%;
    background-color: #fff; /* 画布背景色 */
    position: relative; /* 使内部元素能够使用绝对定位 */
  }
  .closeGraphLayer{
    position: absolute;
    bottom:50px;
    right:50px;
    z-index: 999;
  }
  .layer{
    position: relative;
  }
  </style>